package cn.com.shinho.hg.core.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @program: hg-server-parent
 * @description: ${description}
 * @author: Mr.Ye
 * @create: 2018-08-24
 **/
public class JsonUtil {
    private static final Logger logger = LoggerFactory.getLogger(JsonUtil.class);

    private final static ObjectMapper objectMapper = new ObjectMapper();

    private JsonUtil() {
    }

    /**
     * @Description: 将对象序列号成Json
     * @Param: [obj]
     * @return: java.lang.String
     * @Author: Mr.Ye
     * @Date: 2018/8/24 16:13
     */
    public static String toJson(Object obj) {

        try {
            return objectMapper.writeValueAsString(obj);
        } catch (IOException e) {
            logger.error("toJson(Object)", e);
        }
        return null;
    }


    /**
     * @Description: 将JSON字符序列化成对象
     * @Param: [json, valueType]
     * @return: T
     * @Author: Mr.Ye
     * @Date: 2018/8/24 16:18
     */
    public static <T> T toObject(String json, Class<T> valueType) {

        try {
            return objectMapper.readValue(json, valueType);
        } catch (IOException e) {
            logger.error("toObject(String, Class<T>)", e);
        }
        return null;
    }


    /**
     * @Description: 将JSON字符序列化成对象(复杂结构对象)
     * @Param: [json, typeReference]
     * @return: T
     * @Author: Mr.Ye
     * @Date: 2018/8/24 16:19
     */
    public static <T> T toObject(String json, TypeReference<T> typeReference) {

        try {
            return objectMapper.readValue(json, typeReference);
        } catch (IOException e) {
            logger.error("toObject(String, JsonTypeReference<T>)", e);
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @Description: 将JSON中某个KEY序列化成对象
     * @Param: [json, valueType, key]
     * @return: java.util.List<T>
     * @Author: Mr.Ye
     * @Date: 2018/8/24 17:06
     */
    public static <T> List<T> toObjectByKey(String json, Class<T> valueType, String key) {

        List<T> arrayList = new ArrayList<T>();
        try {
            List<JsonNode> jsonNodeList = objectMapper.readTree(json).findValues(key);
            for (JsonNode jsonNode : jsonNodeList) {
                arrayList.add(objectMapper.readValue(jsonNode.toString(), valueType));
            }
            return arrayList;
        } catch (IOException e) {
            logger.error("toObjectByKey(String , Class<T> ,String )", e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description: 将JSON中某个KEY序列化成对象(复杂对象)
     * @Param: [json, typeReference, key]
     * @return: java.util.List<T>
     * @Author: Mr.Ye
     * @Date: 2018/8/24 17:11
     */
    public static <T> List<T> toObjectByKey(String json, TypeReference<T> typeReference, String key) {

        List<T> arrayList = new ArrayList<T>();
        try {
            List<JsonNode> jsonNodeList = objectMapper.readTree(json).findValues(key);
            for (JsonNode jsonNode : jsonNodeList) {
                arrayList.add(objectMapper.readValue(jsonNode.toString(), typeReference));
            }
            return arrayList;
        } catch (IOException e) {
            logger.error("toObjectByKey(String , TypeReference<T> ,String )", e);
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @Description: 查找JSON中的字符串
     * @Param: [json, key]
     * @return: java.lang.String
     * @Author: Mr.Ye
     * @Date: 2018/8/24 17:20
     */
    public static String getJsonInKey(String json, String key) {

        StringBuilder stringBuilder = new StringBuilder();
        try {
            List<JsonNode> jsonNodeList = objectMapper.readTree(json).findValues(key);
            for (JsonNode jsonNode : jsonNodeList) {
                stringBuilder.append(jsonNode.toString());
            }
            return stringBuilder.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description: 将String Json转成Json对象
     * @Param: [json]
     * @return: com.fasterxml.jackson.databind.JsonNode
     * @Author: Mr.Ye
     * @Date: 2018/8/29 10:55
     */
    public static JsonNode parseJsonNode(String json) {
        try {
            return objectMapper.readTree(json);
        } catch (IOException e) {
            logger.error("parseJsonNode(String json )", e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description: 清除null节点
     * @Param: [json]
     * @return: java.lang.String
     * @Author: Mr.Ye
     * @Date: 2018/8/29 11:45
     */
    public static String clearWhiteSpace(@Nullable String json) {
        try {
            JsonNode jsonNode = objectMapper.readTree(json);
            if (jsonNode != null) {
                Iterator<Map.Entry<String, JsonNode>> iterator = jsonNode.fields();
                while (iterator.hasNext()) {
                    Map.Entry<String, JsonNode> mapNode = iterator.next();
                    JsonNode nodeValue = mapNode.getValue();
                    if (nodeValue != null) {
                        String text = nodeValue.asText().trim();
                        mapNode.setValue(objectMapper.readTree(text));
                    }
                }
            } else {
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
